#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTextEdit>
#include <QMessageBox>
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("T810-Tool V1.0.0--霞智科技有限公司");

    search_serial_port();
    candevice = new CanDevice();
    thread_rx = new QThread();
    thread_tx = new QThread();
    CanDevice *can_rx = new CanDevice();
    can_rx->moveToThread(thread_rx);
    CanDevice * can_tx = new CanDevice();
    can_tx->moveToThread(thread_tx);

    http_thread = new HttpThread(this);
    http_thread->startWorking();

    websocket_thread = new WebsocketThread(this);
    websocket_thread->startWorking();

    connect(thread_rx, &QThread::started, can_rx, &CanDevice::canRecvData);
    connect(thread_tx, &QThread::started, can_tx, &CanDevice::canSendData);

    connect(can_rx, &CanDevice::updateSignal, this, &MainWindow::update_text_lable);
    connect(can_rx, &CanDevice::updateParam, this, &MainWindow::updata_bud_param_lable);

    connect(ui->brush_power_gear1, &QLineEdit::editingFinished, this, &MainWindow::brush_power_gear1_TextChange);
    connect(ui->brush_power_gear2, &QLineEdit::editingFinished, this, &MainWindow::brush_power_gear2_TextChange);
    connect(ui->brush_power_gear3, &QLineEdit::editingFinished, this, &MainWindow::brush_power_gear3_TextChange);

    thread_tx->start();
    thread_rx->start();
}

MainWindow::~MainWindow()
{
    http_thread->stopWorking();
    websocket_thread->stopWorking();
    delete ui;
}

uint32_t MainWindow::stringToUint(QString str)
{
    bool ok;
    uint32_t number = str.toUInt(&ok);
    if(ok)
    {
        qDebug()<< "number:"<<number ;
        return number ;
    }
    else
    {
        return false;
    }
}

QString MainWindow::uintToString(uint32_t data)
{
  QString version = "V"+ QString::number(data>>16&0xFF) +"."
                      + QString::number((data>>8)&0xFF) +"."
                      + QString::number((data)&0xFF);
    return version ;
}

void MainWindow::search_serial_port()
{
    QList<QSerialPortInfo> list = QSerialPortInfo::availablePorts();
    for(int i=0; i<list.size(); i++)
    {
        ui->comboBox_port->addItem(list.at(i).portName());
    }
    //创建串口对象
    serial = new QSerialPort;
    //连接信号与槽（接收数据）
    QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);
}

QByteArray MainWindow::hexStringToByteArray(const QString &hexString)
{
    QByteArray byteArray;

    QString sanitizedHex = hexString;//确保字符串长度是偶数
    if (sanitizedHex.length() % 2 != 0){
        sanitizedHex.prepend('0');//如果长度是奇数，前面补零
    }
    for (int i=0; i<sanitizedHex.length(); i+=2)
    {
        QString byteString = sanitizedHex.mid(i,2);//取两位
        bool ok;
        byteArray.append(static_cast<char>(byteString.toInt(&ok,16)));//转为字节
        if (!ok){
            qDebug() << "Invalid hex byte:" << byteString;//字符串非16进制格式，转换报错
        }
    }
    return byteArray;//返回转换结果

}

void MainWindow::on_connet_button_clicked()
{
    if(ui->connet_button->text() == tr("打开连接"))
    {
        if(candevice->ConnetCAN())
        {
            qDebug()<<"打开连接";
            ui->connet_button->setText("已连接");
        }
        else
        {
            QMessageBox::warning(this, tr("警告"), tr("can设备打开异常"));
        }
    }
    else if(ui->connet_button->text() == tr("已连接"))
    {
        qDebug()<<"关闭连接";
        ui->connet_button->setText("打开连接");
        candevice->CloseCAN();
    }

}
void MainWindow::update_text_lable(Param *param)
{
    updata_bdu_status(param);
    updata_hou_status(param);
    updata_wdu_status(param);
    updata_pmu_status(param);
}

void MainWindow::updata_hou_status(Param *param)
{
    ui->clean_start_key->setText(param->clean_start_key);
    ui->suction_start_key->setText(param->suction_start_key);
    ui->crash->setText(param->crash);
    ui->pressure->setText(param->pressure);
    ui->epf->setText(param->epf);
    ui->forward_key->setText(param->front_key);
    ui->back_key->setText(param->back_key);
    ui->pause_key->setText(param->pause_key);
    ui->speaker->setText(param->speaker);
    ui->front_led_key->setText(param->front_led_key);
    ui->speed->setText(param->set_speed);
    ui->nfc->setText(param->nfc);
    ui->slope_angle->setText(param->slope_angel);

}
  //清洁业务版
void MainWindow::updata_bdu_status(Param *param)
{
    ui->left_brush_gear->setText(param->left_brush);
    ui->right_brush_gear->setText(param->right_brush);
    ui->brush_push_status->setText(param->brushpush);
    ui->water_push_status->setText(param->waterpush);
    ui->suction_gear->setText(param->suction);
    ui->spray_water_gear->setText(param->spraygear);
    ui->top_flash_led->setText(param->topledflash);
    ui->front_spotlight->setText(param->frontled);
    ui->dirty_drain->setText(param->dirty_drain);
    ui->clean_drain->setText(param->clean_drain);
    ui->clean_soc->setText(param->clean);
    ui->clean_empty->setText(param->clean_empty);
    ui->dirty_soc->setText(param->dirty);
    ui->dirty_full->setText(param->dirty_full);
}

void MainWindow::updata_wdu_status(Param *param)
{
    ui->run_motor_status->setText(param->run_motor_status);
    ui->run_motor_error->setText(param->run_motor_error);
    ui->run_motor_speed->setText(param->run_motor_speed);
    ui->motor_type->setText(param->run_motor_type);

    ui->steer_motor_error->setText(param->steer_motor_error);
    ui->steer_angle->setText(param->steer_angle);
    ui->emergency_wdu->setText(param->emergency_wdu);
}

void MainWindow::updata_pmu_status(Param *param)
{
    ui->current->setText(param->current);
    ui->vol->setText(param->vol);
    ui->soc->setText(param->soc);
    ui->bms_status->setText(param->bms_status);
    ui->tempratue->setText(param->temprature);

    ui->acc_key->setText(param->acc_key);
    ui->emergency_pmu->setText(param->emergency_pmu);
    ui->handle_detect->setText(param->handle_detect);
    ui->left_detecte->setText(param->handle_detect);
    ui->right_detecte->setText(param->handle_detect);
}

void MainWindow::updata_bud_param_lable(OdParam *odparam)
{
    updata_mcu_version(odparam);
    updata_bdu_param(odparam);
}
void MainWindow::updata_mcu_version(OdParam *odparam)
{
    ui->software_version_hou->setText(uintToString(odparam->soft_version_hou));
    ui->software_version_bdu->setText(uintToString(odparam->soft_version_bdu));
    ui->software_version_pmu->setText(uintToString(odparam->soft_version_pmu));
    ui->software_version_wdu->setText(uintToString(odparam->soft_version_wdu));
}

void MainWindow::updata_bdu_param(OdParam *odparam)
{
    ui->water_suck_down_time_default->setText(QString::number(odparam->water_suck_down_time_default));
    ui->water_suck_delay_up_time_default->setText(QString::number(odparam->water_suck_delay_up_time_default));
    ui->brush_push_down_time_default->setText(QString::number(odparam->brush_push_down_time_default));
    ui->brush_push_down_time_max->setText(QString::number(odparam->brush_push_down_time_max));
    ui->suction_delay_off_time_default->setText(QString::number(odparam->suction_delay_off_time_default));

    ui->spray_water_duty_gear1->setText(QString::number(odparam->spray_water_duty_gear1));
    ui->spray_water_duty_gear2->setText(QString::number(odparam->spray_water_duty_gear2));
    ui->spray_water_duty_gear3->setText(QString::number(odparam->spray_water_duty_gear3));
    ui->left_right_brush_duty_default->setText(QString::number(odparam->left_right_brush_duty_default));
    ui->suction_duty_default->setText(QString::number(odparam->suction_duty_default));
    ui->brush_power_gear1->setText(QString::number(odparam->brush_power_gear1));
    ui->brush_power_gear2->setText(QString::number(odparam->brush_power_gear2));
    ui->brush_power_gear3->setText(QString::number(odparam->brush_power_gear3));
    ui->pump_type->setText(QString::number(odparam->pump_type));
    ui->brush_push_overload->setText(QString::number(odparam->brush_push_overload));
    ui->spray_water_duty_gear1->setText(QString::number(odparam->spray_water_duty_gear1));

}

void MainWindow::on_read_param_clicked()
{
    uint8_t buf[8] = {0x40,0x80,0x30,0x00,0x00,0x00,0x00,0x00};
    for(int i = 0 ; i < 6 ; i++)
    {
        buf[3] = i ;
        candevice->canTransmitData(0x513 , sizeof(buf) ,buf );
        QThread::msleep(10);
    }
    for(int i = 0 ; i < 10 ; i++)
    {
        buf[1] = 0x81 ;
        buf[3] = i ;
        candevice->canTransmitData(0x513 , sizeof(buf) ,buf );
        QThread::msleep(10);
    }
    for(int i = 0x10 ; i < 0x13 ; i++)
    {
        buf[1] = 0x81 ;
        buf[3] = i ;
        candevice->canTransmitData(0x513 , sizeof(buf) ,buf );
        QThread::msleep(10);
    }
}

void MainWindow::on_get_mcu_version_clicked()
{
    uint8_t buf[8] = {0x40,0x00,0x32,0x00,0x00,0x00,0x00,0x00};
    for(int i = 1 ; i < 5 ; i++)
    {
      candevice->canTransmitData(0x510+i , sizeof(buf) ,buf );
      QThread::msleep(10);
    }
}

void MainWindow::brush_power_gear1_TextChange()
{
    QString text = ui->brush_power_gear1->text();
    qDebug() << "Text changed:" << text;
}
void MainWindow::brush_power_gear2_TextChange()
{
    uint8_t buf[8] = {0x23,0x81,0x30,0x06,0x00,0x00,0x00,0x00};
    QString text = ui->brush_power_gear2->text();
    qDebug() << "Text changed:" << text;
    uint32_t data = stringToUint(text);
    buf[7] = static_cast<uint8_t>((data >> 24) & 0xFF);
    buf[6]= static_cast<uint8_t>((data >> 16) & 0xFF);
    buf[5] = static_cast<uint8_t>((data >> 8) & 0xFF);
    buf[4] = static_cast<uint8_t>(data & 0xFF);
    qDebug()<< data ;
    candevice->canTransmitData(0x513 , sizeof(buf) ,buf );
}
void MainWindow::brush_power_gear3_TextChange()
{
    QString text = ui->brush_power_gear3->text();
    qDebug() << "Text changed:" << text;
}


void MainWindow::on_open_serial_port_clicked()//点击打开串口按钮
{
    if(ui->open_serial_port->text() == "打开串口")
    {
        //设置串口为下拉栏所选串口名
        serial->setPortName(ui->comboBox_port->currentText());
        //设置波特率
        serial->setBaudRate(QSerialPort::Baud115200);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);//无流控制
        //打开串口 同时判断是否成功
        bool info = serial->open(QIODevice::ReadWrite);
        if(info == true)
        {
            qDebug()<<"success";
            //改变按钮文本为“关闭串口”
            ui->open_serial_port->setText(tr("关闭串口"));
        }
        else
        {
            qDebug()<<"fail";
        }
    }
    else
    {   //关闭串口
        serial->clear();
        serial->close();
        ui->open_serial_port->setText(tr("打开串口"));
    }
}

void MainWindow::ReadData()//接收数据函数（并显示）
{
    QByteArray buf = serial->readAll();
    if(ui->checkBox_display->isChecked()==true)//已经被勾选
    {
        QString hexData= buf.toHex().toUpper();//将数据转换为16进制字符串并大写
        QString spacedData;//用于存储每个字节隔开一个空格的字符串
        for(int i=0;i<hexData.length();i+=2)//在每个字节后添加一个空格
        {
            spacedData += hexData.mid(i,2);
            spacedData += " ";
        }
        QString currentTime = QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss]");//定义字符串 = 当前时间并转换为字符串
        ui->textBrowser->append(currentTime);//设置标签内容
        ui->textBrowser->append(spacedData);//将转换后的数据显示
    }
    else
    {
        QString currentTime = QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss]");//定义字符串 = 当前时间并转换为字符串
        ui->textBrowser->append(currentTime);//设置标签内容
        ui->textBrowser->append(buf);//未勾选则直接显示
    }
}

void MainWindow::on_send_data_clicked()//点击发送按钮
{
    //检查串口是否打开
    if (serial->isOpen())
    {
        if(ui->checkBox_send->isChecked()==true)//16进制发送被选中
        {
            //获取要发送的数据：lineEdit_send内容
            QString sendData = ui->lineEdit->text();
            //将字符串转换为QByteArray形式（调用了hexStringToByteArray函数）
            QByteArray data  = hexStringToByteArray(sendData);
            //发送数据
            serial->write(data);
        }
        else
        {
            //获取要发送的数据：lineEdit_send内容
            QString sendData = ui->lineEdit->text();
            //将字符串转为QByteArray
            QByteArray data  = sendData.toUtf8();
            //发送数据
            serial->write(data);
        }
    }
    else { qDebug()<<"serial is not open";}

}

void MainWindow::on_clear_recv_clicked()
{
    ui->textBrowser->clear();
}


void MainWindow::on_find_serial_clicked()
{
    //获取可用串口名到下拉栏
    QList<QSerialPortInfo> list = QSerialPortInfo::availablePorts();
    for(int i=0; i<list.size(); i++)
    {
        ui->comboBox_port->addItem(list.at(i).portName());

    }
}

